package cn.mrlong.base.view

import android.util.Log
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import cn.mrlong.base.bean.Message
import cn.mrlong.base.bean.MessageType
import cn.mrlong.base.ktnet.baseconfig.BaseResponse
import cn.mrlong.base.ktnet.err.FactoryException
import kotlinx.coroutines.*

import kotlinx.coroutines.Dispatchers

/**
 * 作者：BINGO
 * 时间：2021/04/06 16:22
 */
open class BaseViewModel : ViewModel(), LifecycleObserver {
    //提示弹窗消息（dialog 或者 toast 通过 MessageType区分）
    val noticeMessage = MutableLiveData<Message>();

    //网络加载进度条
    val progressBarState = MutableLiveData<Boolean>()

    //显示message
    fun message(type: MessageType, message: Any? = null) {
        noticeMessage.value = Message(type, message)
    }

    fun <T> request(
        request: suspend () -> BaseResponse<T>?,
        onSuccess: (T?) -> Unit = {},
        onFail: (String?) -> Unit = {},
        isShowProgress: Boolean = true
    ): Job {
        if (isShowProgress) {
            progressBarState.value = true
        }
        return viewModelScope.launch(Dispatchers.Main) {
            kotlin.runCatching {
                withContext(Dispatchers.IO) {
                    request()
                }
            }.onSuccess {
                if (isShowProgress) {
                    progressBarState.value = false
                }
                if (null != it) {
                    if (!it.isSuccess()) {
                        noticeMessage.value = Message(
                            MessageType.DIALOG,
                            it.message ?: FactoryException.SERVER_DATA_NULL
                        )
                    } else {
                        onSuccess(it.data)
                    }
                }
            }.onFailure {
                if (isShowProgress) {
                    progressBarState.value = false
                }
                it.printStackTrace()
                it?.run {
                    if (it is CancellationException) {

                    } else {
                        noticeMessage.value =
                            Message(MessageType.TOAST, FactoryException.analysisExcetpion(it))
                    }
                    it.message?.let { it1 -> Log.e("", it1) }
                    onFail(it.message)
                }
            }
        }
    }
}